package com.horay.statemachiedemo.multi.controller;

import com.horay.statemachiedemo.multi.builder.FormStateMachineBuilder;
import com.horay.statemachiedemo.multi.enums.FormState;
import com.horay.statemachiedemo.multi.event.FormEvent;
import com.horay.statemachiedemo.multi.model.Form;
import com.horay.statemachiedemo.multi.model.Order;
import com.horay.statemachiedemo.multi.persist.MemoryStateMachineMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Class description
 *
 * @author heyingcheng
 * @date 2020/10/23
 */
@Slf4j
@RestController
public class FormController {

    private final BeanFactory beanFactory;

    private final FormStateMachineBuilder formStateMachineBuilder;

    private final StateMachinePersister<FormState, FormEvent, String> formStateMachinePersister;

    public FormController(BeanFactory beanFactory, FormStateMachineBuilder formStateMachineBuilder, StateMachinePersister<FormState, FormEvent, String> formStateMachinePersister) {
        this.beanFactory = beanFactory;
        this.formStateMachineBuilder = formStateMachineBuilder;
        this.formStateMachinePersister = formStateMachinePersister;
    }

    @PostMapping("/form/write")
    public String write(String formId) throws Exception {

        StateMachine<FormState, FormEvent> stateMachine = formStateMachineBuilder.build(beanFactory);
        // 创建流程
        stateMachine.start();
        // 触发WRITE事件
        Form form = new Form(formId, "WRITE-547568678", "WRITE-广东省深圳市");
        Message<FormEvent> message = MessageBuilder.withPayload(FormEvent.WRITE).setHeader(Form.class.getName(), form).build();
        stateMachine.sendEvent(message);
        // 获取状态
        log.info("FormId:[{}], State:[{}]", formId, stateMachine.getState().getId());
        formStateMachinePersister.persist(stateMachine, form.getFormId());
        return "SUCCESSS";

    }

    @PostMapping("/form/confirm")
    public String confirm(String formId) throws Exception {

        StateMachine<FormState, FormEvent> stateMachine = formStateMachineBuilder.build(beanFactory);
        stateMachine = formStateMachinePersister.restore(stateMachine, formId);
        // 触发CONFIRM事件
        Form form = new Form(formId, "CONFIRM-547568678", "CONFIRM-广东省深圳市");
        Message<FormEvent> message = MessageBuilder.withPayload(FormEvent.CONFIRM).setHeader(Form.class.getName(), form).build();
        stateMachine.sendEvent(message);
        // 获取状态
        log.info("FormId:[{}], State:[{}]", formId, stateMachine.getState().getId());
        formStateMachinePersister.persist(stateMachine, form.getFormId());
        return "SUCCESSS";

    }

    @PostMapping("/form/submit")
    public String submit(String formId) throws Exception {

        StateMachine<FormState, FormEvent> stateMachine = formStateMachineBuilder.build(beanFactory);
        stateMachine = formStateMachinePersister.restore(stateMachine, formId);
        // 触发SUBMIT事件
        Form form = new Form(formId, "SUBMIT-547568678", "SUBMIT-广东省深圳市");
        Message<FormEvent> message = MessageBuilder.withPayload(FormEvent.SUBMIT).setHeader(Form.class.getName(), form).build();
        stateMachine.sendEvent(message);
        // 获取状态
        log.info("FormId:[{}], State:[{}]", formId, stateMachine.getState().getId());
        formStateMachinePersister.persist(stateMachine, form.getFormId());
        return "SUCCESSS";

    }

    @PostMapping("/form/send/event")
    public String sendEvent(String formId, String event) throws Exception {

        StateMachine stateMachine = MemoryStateMachineMap.FORM_STATE_MACHINE_MAP.get(formId);
        Form form = new Form();
        form.setFormId(formId);
        if (stateMachine == null) {
            if (FormEvent.SUBMIT.name().equals(event)) {
                stateMachine = formStateMachineBuilder.build(beanFactory);
                stateMachine.start();
                MemoryStateMachineMap.FORM_STATE_MACHINE_MAP.put(formId, stateMachine);
            } else {
                log.info("该订单流程尚未开始，不能做[{}]转换", event);
                return "ERROR";
            }
            Message message = MessageBuilder.withPayload(FormEvent.valueOf(event)).setHeader(Order.class.getName(), form).setHeader("TestFormObject", "TestFormObject").build();
            stateMachine.sendEvent(message);
        }
        return "SUCCESSS";

    }

    @PostMapping("/form/redis/persister")
    public void formRedisPersister(String formId) throws Exception {
        StateMachine<FormState, FormEvent> stateMachine = formStateMachineBuilder.build(beanFactory);
        stateMachine.start();
        Form form = new Form();
        form.setFormId(formId);
        // 发送SUBMIT事件
        Message<FormEvent> message = MessageBuilder.withPayload(FormEvent.SUBMIT).setHeader(Form.class.getName(), form).build();
        stateMachine.sendEvent(message);
        // 持久化stateMachine
        formStateMachinePersister.persist(stateMachine, form.getFormId());
    }

    @PostMapping("/form/redis/persister/restore")
    public void testRestore(String formId) throws Exception {

        StateMachine<FormState, FormEvent> stateMachine = formStateMachineBuilder.build(beanFactory);
        formStateMachinePersister.restore(stateMachine, formId);
        log.info("FormId:[{}], 恢复状态机后的状态为:[{}]", formId, stateMachine.getState().getId());

    }

}
